package com.spzx.channel.service.impl;

import com.alibaba.fastjson.JSON;
import com.spzx.channel.domain.ItemVo;
import com.spzx.channel.service.IItemService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.Product;
import com.spzx.product.api.domain.ProductDetails;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.SkuPrice;
import com.spzx.product.api.domain.vo.SkuStockVo;
import com.spzx.user.api.RemoteUserInfoService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Author GQS @Date 2024/9/29/19:05 @Description
 */
@Service
@Slf4j
public class ItemServiceImpl implements IItemService {
  @Autowired
  private RemoteProductService remoteProductService;
  @Autowired
  private RedissonClient redissonClient;

  @Autowired
  private ThreadPoolExecutor threadPoolExecutor;

  @Autowired
  private RemoteUserInfoService remoteUserInfoService;

    /**
   * 客户端商品详细页面信息
   * 单线程 耗时40ms
   * @param skuId
   * @return
   */

  // @Override
  // public ItemVo item(Long skuId) {
  // long start = System.currentTimeMillis();
  //
  //   //远程调用商品微服务接口之前 提前知道用户访问商品SKUID是否存在与布隆过滤器
  //   RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter("sku:bloom:filter");
  //   if (!bloomFilter.contains(skuId)) {
  //     log.error("用户查询商品sku不存在：{}", skuId);
  //     //查询数据不存在直接返回空对象
  //     throw new ServiceException("用户查询商品sku不存在");
  //   }
  //
  //   ItemVo itemVo = new ItemVo();
  //   //获取sku信息
  //   R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
  //   if (R.FAIL == productSkuResult.getCode()) {
  //     throw new ServiceException(productSkuResult.getMsg());
  //   }
  //   ProductSku productSku = productSkuResult.getData();
  //   itemVo.setProductSku(productSku);
  //
  //   //获取商品信息
  //   R<Product> productResult = remoteProductService.getProduct(productSku.getProductId(), SecurityConstants.INNER);
  //   if (R.FAIL == productResult.getCode()) {
  //     throw new ServiceException(productResult.getMsg());
  //   }
  //   Product product = productResult.getData();
  //   itemVo.setProduct(product);
  //   // 将轮播图字符串转为list,分割符为逗号
  //   itemVo.setSliderUrlList(Arrays.asList(product.getSliderUrls().split(",")));
  //   // 将商品规格json转为list
  //   itemVo.setSpecValueList(JSON.parseArray(product.getSpecValue()));
  //
  //   //获取商品最新价格
  //   R<SkuPrice> skuPriceResult = remoteProductService.getSkuPrice(skuId, SecurityConstants.INNER);
  //   if (R.FAIL == skuPriceResult.getCode()) {
  //     throw new ServiceException(skuPriceResult.getMsg());
  //   }
  //   SkuPrice skuPrice = skuPriceResult.getData();
  //   itemVo.setSkuPrice(skuPrice);
  //
  //   //获取商品详情
  //   R<ProductDetails> productDetailsResult = remoteProductService.getProductDetails(productSku.getProductId(), SecurityConstants.INNER);
  //   if (R.FAIL == productDetailsResult.getCode()) {
  //     throw new ServiceException(productDetailsResult.getMsg());
  //   }
  //   ProductDetails productDetails = productDetailsResult.getData();
  //   // 将详情图片字符串转为list,分割符为逗号
  //   itemVo.setDetailsImageUrlList(Arrays.asList(productDetails.getImageUrls().split(",")));
  //
  //   //获取商品规格对应商品skuId信息
  //   R<Map<String, Long>> skuSpecValueResult = remoteProductService.getSkuSpecValue(productSku.getProductId(), SecurityConstants.INNER);
  //   if (R.FAIL == skuSpecValueResult.getCode()) {
  //     throw new ServiceException(skuSpecValueResult.getMsg());
  //   }
  //   Map<String, Long> skuSpecValueMap = skuSpecValueResult.getData();
  //   itemVo.setSkuSpecValueMap(skuSpecValueMap);
  //
  //   //获取商品库存信息
  //   R<SkuStockVo> skuStockResult = remoteProductService.getSkuStock(skuId, SecurityConstants.INNER);
  //   if (R.FAIL == skuStockResult.getCode()) {
  //     throw new ServiceException(skuStockResult.getMsg());
  //   }
  //   SkuStockVo skuStockVo = skuStockResult.getData();
  //   itemVo.setSkuStockVo(skuStockVo);
  //
  // long end = System.currentTimeMillis();
  //   log.info("单线程耗时：{}", end - start);
  //
  //   return itemVo;
  // }

  /**
   * 多线程 耗时20ms
   * @param skuId
   * @return
   */
  @Override
  public ItemVo item(Long skuId) {
      long start = System.currentTimeMillis();
      //1.远程调用商品微服务接口之前 提前知道用户访问商品skuID是否存在与布隆过滤器
    RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter("sku:bloom:filter");
    if (!bloomFilter.contains(skuId)){
      log.error("用户查询商品sku不存在：{}", skuId);
      //查询数据不存在直接返回空对象
      throw new ServiceException("用户查询商品sku不存在");
    }
    ItemVo itemVo = new ItemVo();
    // 2.异步获取产品SKU信息
    CompletableFuture<ProductSku> skuCompletableFuture = CompletableFuture.supplyAsync(() -> {
        // 调用远程服务获取产品SKU
        R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
        // 如果请求失败，抛出服务异常
        if (R.FAIL == productSkuResult.getCode()) {
            throw new ServiceException(productSkuResult.getMsg());
        }
        // 提取并设置产品SKU信息到ItemVo
        ProductSku productSku = productSkuResult.getData();
        itemVo.setProductSku(productSku);
        // 返回产品SKU信息
        return productSku;
    }, threadPoolExecutor);
    // 3.获取商品信息
      CompletableFuture<Void> productCompletableFuture = skuCompletableFuture.thenAcceptAsync(productSku -> {
          R<Product> productResult = remoteProductService.getProduct(productSku.getProductId(), SecurityConstants.INNER);
          if (R.FAIL == productResult.getCode()) {
              throw new ServiceException(productResult.getMsg());
          }
          // 提取并设置商品信息到ItemVo
          Product product = productResult.getData();
          itemVo.setProduct(product);
          // 设置轮播图
          itemVo.setSliderUrlList(Arrays.asList(product.getSliderUrls().split(",")));
          // 设置规格详细信息
          itemVo.setSpecValueList(JSON.parseArray(product.getSpecValue()));
      }, threadPoolExecutor);
      // 4.获取商品最新信息
      CompletableFuture<Void> skuPriceCompletableFuture = CompletableFuture.runAsync(() -> {
          R<SkuPrice> skuPriceResult = remoteProductService.getSkuPrice(skuId, SecurityConstants.INNER);
          if (R.FAIL == skuPriceResult.getCode()) {
              throw new ServiceException(skuPriceResult.getMsg());
          }
          // 提取并设置最新价格到ItemVo
          itemVo.setSkuPrice(skuPriceResult.getData());
      }, threadPoolExecutor);
      // 5.获取商品详情
      CompletableFuture<Void> productDetailsComCompletableFuture = skuCompletableFuture.thenAcceptAsync(productSku -> {
          R<ProductDetails> productDetailsResult = remoteProductService.getProductDetails(productSku.getProductId(), SecurityConstants.INNER);
          if (R.FAIL == productDetailsResult.getCode()) {
              throw new ServiceException(productDetailsResult.getMsg());
          }
          ProductDetails productDetails = productDetailsResult.getData();
          itemVo.setDetailsImageUrlList(Arrays.asList(productDetails.getImageUrls().split(",")));
      }, threadPoolExecutor);
      // 6.获取商品规格对应商品skuId信息
      CompletableFuture<Void> skuSpecValueComCompletableFuture = skuCompletableFuture.thenAcceptAsync(productSku -> {
          R<Map<String, Long>> skuSpecValueResult = remoteProductService.getSkuSpecValue(productSku.getProductId(), SecurityConstants.INNER);
          if (R.FAIL == skuSpecValueResult.getCode()) {
              throw new ServiceException(skuSpecValueResult.getMsg());
          }
          Map<String, Long> skuSpecValueMap = skuSpecValueResult.getData();
          itemVo.setSkuSpecValueMap(skuSpecValueMap);
      }, threadPoolExecutor);
      // 7.获取商品库存信息
      CompletableFuture<Void> skuStockVoComCompletableFuture = CompletableFuture.runAsync(() -> {
          R<SkuStockVo> skuStockResult = remoteProductService.getSkuStock(skuId, SecurityConstants.INNER);
          if (R.FAIL == skuStockResult.getCode()) {
              throw new ServiceException(skuStockResult.getMsg());
          }
          SkuStockVo skuStockVo = skuStockResult.getData();
          itemVo.setSkuStockVo(skuStockVo);
      }, threadPoolExecutor);
      //8.组合以上七个异步任务
      CompletableFuture.allOf(
              skuCompletableFuture,
              productCompletableFuture,
              skuPriceCompletableFuture,
              productDetailsComCompletableFuture,
              skuSpecValueComCompletableFuture,
              skuStockVoComCompletableFuture
      ).join(); // join() 方法阻塞当前线程直到所有任务完成
        // 返回结果
      long end = System.currentTimeMillis();
      log.info("多线程耗时：{} ms", end - start);
      // 添加浏览历史
      remoteUserInfoService.addBrowseHistory(skuId, SecurityConstants.INNER);
      return itemVo;
  }

}
